# -*- coding: utf-8 -*-
# 该文件在 docker 内执行，需要传入当前主机/路由器的名称，如："D1" 或 "R1"

import sys
import os
import telnetlib
from config import config, router

tn = None

def start_telnet(port: int):
    global tn
    tn = telnetlib.Telnet(host="127.0.0.1", port=port)
    tn.read_until(": ".encode('ascii'))
    # 输入密码：zebra
    tn.write("zebra\n".encode('ascii'))
    tn.read_until("> ".encode('ascii'))
    # 进入特权模式
    tn.write("en\n".encode('ascii'))
    # 修改配置文件
    telnet("config t")

def telnet(codes: str):
    global tn
    codes = codes + "\n"
    tn.read_until("# ".encode('ascii'))
    tn.write(codes.encode('ascii'))

def close_telnet():
    global tn
    telnet("end")
    telnet("copy running-config startup-config")
    tn.close()

def config_net(r: router(), area=-1):
    for i in range(len(r.interfaces_ip)):
        net = r.get_network_ip(index=i) + "/24"
        if area != -1:
            net = net+" area "+str(area)
        telnet(f"network {net}")

if __name__ == "__main__":
    # 外部调用该 py 文件时，需要传入参数，代表当前配置的设备名称，如："D1" 或 "R1"
    inputs = sys.argv[1]
    if not inputs:
        exit()
    num = int(inputs[1:]) - 1

    config = config()

    if inputs[0] == "D" or inputs[0] == "d":
        r = config.devices[num]
    elif inputs[0] == "R" or inputs[0] == "r":
        r = config.routers[num]
    else:
        exit()


    """1. 配置主机网络"""
    for i in range(len(r.interfaces_ip)):
        net_name = r.get_network_name(i) + r.interfaces_ip[i][-1:]
        net_ip = r.interfaces_ip[i]
        os.system(f"ifconfig {net_name} {net_ip} netmask 255.255.255.0 up")
    if r.type == 0:
        # 为主机配置默认路由，主机只有一个网络接入
        nip = r.get_network_ip(0)
        ip = nip[:-1] + '1'
        os.system(f"route add default gw {ip}")
    else:
        os.system("zebra -d")
        os.system("echo '1'>/proc/sys/net/ipv4/ip_forward")

    """2. 配置 quagga"""
    if r.type == 3:
        os.system("ripd -d")
        os.system("ospfd -d")
        # 配置 rip
        start_telnet(2602)
        telnet(f"router rip")
        config_net(r=r)
        telnet("redistribute ospf metric 10")
        close_telnet()
        # 配置 ospf
        start_telnet(2604)
        telnet(f"router ospf")
        config_net(r=r, area=0)
        telnet("redistribute rip metric 10")
        close_telnet()
    else:
        if r.type == 1:
            # 配置 rip
            os.system("ripd -d")
            start_telnet(2602)
            telnet(f"router rip")
            config_net(r=r)
        elif r.type == 0 or r.type == 2:
            # 配置 ospf
            os.system("ospfd -d")
            start_telnet(2604)
            telnet(f"router ospf")
            config_net(r=r, area=0)
        close_telnet()
